<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>abc</title>
  </head>
  <body>
    <script>
      // async function getTodo() {
      //   const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
      //   console.log("res", res.json());
      //   return  res
      // }
      // getTodo();

      let urls = [];
      for (let i = 0; i < 10; i++) {
        urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
      }

      // concurrentRequests(urls, 3).then((res) => {
      //   console.log("请求成功", res);
      // });

      function concurrentRequests(url, maxNum) {
        return new Promise((resolve, reject) => {
          if (!urls.length) {
            resolve([]);
            return;
          }
          let index = 0;
          let i = 0;
          let count = 0;
          const results = [];

          async function request() {
            // if (index === urls.length) {
            //   return
            // }
            const url = urls[index];
            i = index;
            index++;
            try {
              const res = await fetch(url);
              results[i] = res;
            } catch (error) {
              results[i] = error;
            } finally {
              count++;
              console.log("count", count, urls.length);
              if (count === urls.length) {
                resolve(results);
              } else {
                request();
              }
            }
          }
          for (let i = 0; i < maxNum; i++) {
            request();
          }
        });
      }

      // 手写promise
      class MyPromise {
        state = "pending";
        result = undefined;
        handlers = [];

        constructor(executor) {
          const resolve = (data) => {
            this.#changeState("fulfilled", data);
          };

          const reject = (reason) => {
            this.#changeState("rejected", reason);
          };

          try {
            executor(resolve, reject);
          } catch (error) {
            reject(error);
          }
        }

        // 改变状态
        #changeState(state, data) {
          if (state === "pending") return;
          this.state = state;
          this.result = data;
          this.#run();
        }

        isPromise(obj) {
          if (obj && typeof obj?.then === "function") {
            return true;
          }
          return false;
        }

        runTask(fun) {
          setInterval(fun, 0);
        }

        oneRun(callback, resolve, reject) {
          if (typeof callback !== "function") {
            const settled = this.state === "fulfilled" ? resolve : reject;
            settled(this.result);
            return;
          }
          try {
            const data = callback(this.result);
            if (this.isPromise(data)) {
              data.then(resolve, reject);
            } else {
              resolve(data);
            }
          } catch (error) {
            reject(error);
          }
        }

        #run() {
          if (this.state === "pending") return;
          while (this.handlers.length) {
            const { onFulfilled, onRejected, resolve, reject } =
              this.handlers.shift();
            if (this.state === "fulfilled") {
              this.oneRun(onFulfilled, resolve, reject);
            } else {
              this.oneRun(onRejected, resolve, reject);
            }
          }
        }

        // then
        then(onFulfilled, onRejected) {
          return new Promise((resolve, reject) => {
            this.handlers.push({
              onFulfilled,
              onRejected,
              resolve,
              reject,
            });
            this.#run();
          });
        }
      }

      // 测试用例
      const p = new MyPromise((resolve, reject) => {
        // setTimeout(() => {
        resolve("111");
        // }, 1000);
      });

      // p.then(
      //   (res) => {
      //     console.log("res-1", res);
      //     return 1243
      //   },
      //   (err) => {
      //     console.log("err-1", err);
      //   }
      // )

      p.then((res) => {
        return 123;
      }).then((res) => {
        console.log("res-2", res);
      });
    </script>
  </body>
</html>
